package com.nio.c4_黏包半包;

import java.nio.ByteBuffer;

/**
 * @version No one is coming, unless you change yourself!!!
 * @author： pang-yun
 * @date： 2021-05-31 10:09
 */

public class ByteBufferExamTest {
    /*
     *
     * 网络上有多条数据发送给服务器端，数据之间由 \n  间隔
     * 但由于某种原因，数据在接收时，被进行了重新组合，例如原始数据有三条：
     *     Hello,World! \n
     *      I am Herman pang \n
     *       How are you!  \n
     *
     * 变成了下面两个ByteBuffer（黏包、半包）
     *   Hello,World! \nI am Herman pang \nHo
     *       w are you!  \n
     *
     * 现在要求你编写程序，将错乱的数据恢复成按 \n
     *
     * ==在网络编程中,有时会为了编程效率将 数据黏包==
     *
     * */

    public static void main(String[] args) {
        ByteBuffer source = ByteBuffer.allocate(128);
        source.put("Hello,World!\nI am Herman pang\nHo".getBytes());
        split(source);
        source.put("w are you!\n".getBytes());
        split(source);

    }

    public static void split(ByteBuffer byteBuffer) {
        /*黏包的解析思路，找到“\n”，然后将他们分离
         * 新建一个ByteBuffer 将将\n之前的内容写入到新的ByteBuffer中*/

        byteBuffer.flip();
        for (int i = 0; i < byteBuffer.limit(); i++) {
            if (byteBuffer.get(i) == '\n') {
                //找到完整语句的长度

                int length = i + 1 - byteBuffer.position();

                ByteBuffer newBuffer = ByteBuffer.allocate(length);
                //将整个语句放入新建的ByteBuffer中
                for (int j = 0; j < length; j++) {
                    //从原有的byteBuffer将内容读取出来
                    byte b = byteBuffer.get();
                    //写入newBuffer中
                    newBuffer.put(b);
                }
                read(newBuffer);
            }

        }
        byteBuffer.compact();
    }

    public static void read(ByteBuffer buffer) {
        buffer.flip();
        while (buffer.hasRemaining()) {
            byte b = buffer.get();
            System.out.print((char) b);
        }
    }
}
